package com.xiaoyuan.minicore.ioc;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.xiaoyuan.minicore.aop.AOPHelper;
import com.xiaoyuan.minicore.aop.BaseAspect;
import com.xiaoyuan.minicore.aop.Handler;
import com.xiaoyuan.minicore.core.ClassHelper;
import com.xiaoyuan.minicore.ioc.annotation.Bean;
import com.xiaoyuan.minicore.mvc.bean.BaseAction;
import com.xiaoyuan.minicore.tx.TxHanlder;
import com.xiaoyuan.minicore.tx.annotation.Transaction;
import org.apache.commons.collections.CollectionUtils;

/**
 * @Auther: xiaoyuan
 * @Date: 2020/4/28
 * @Description:
 */
public class BeanHelper {

    // Bean 类 => Bean 实例
    private static final Map<Class<?>, Object> beanMap = new HashMap<Class<?>, Object>();

    public static void init() {
        try {
            // 获取并遍历所有的 Bean（带有 @Bean 注解的类）
            List<Class<?>> beanClassList = ClassHelper.getClassListByAnnotation(Bean.class);
            for (Class<?> beanClass : beanClassList) {
                //action不入IOC，action是多例
                if (BaseAction.class.isAssignableFrom(beanClass) && !BaseAction.class.equals(beanClass)) {
                    continue;
                }
                // 创建 Bean 实例
                Object beanInstance;
                Method[] methods = beanClass.getMethods();
                //处理切点
                List<Handler> handlers = new ArrayList<>();
                //1、AOP处理普通自定义切点
                Set<Class> aspects = AOPHelper.getSet(beanClass);
                if (CollectionUtils.isNotEmpty(aspects)) {
                    for (Class clazz : aspects) {
                        handlers.add((Handler) clazz.newInstance());
                    }
                }
                //2、AOP处理tx切点
                boolean shouldTrans = false;
                for (int i = 0; methods != null && i < methods.length; i++) {
                    if (methods[i].isAnnotationPresent(Transaction.class)) {
                        shouldTrans = true;
                        break;
                    }
                }
                if(shouldTrans){
                    handlers.add(new TxHanlder());
                }
                if (CollectionUtils.isNotEmpty(handlers)) {
                    //如果Bean注解中有用方法用transaction注解的，需要用CGLIB进行动态代理，以满足事务需求
                    beanInstance = BaseAspect.class.newInstance().getProxy(beanClass,handlers);
                } else {
                    // 创建 普通Bean 实例
                    beanInstance = beanClass.newInstance();
                }

                // 将 Bean 实例放入 Bean Map 中（键为 Bean 类，值为 Bean 实例）
                beanMap.put(beanClass, beanInstance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Map<Class<?>, Object> getBeanMap() {
        return beanMap;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> cls) {
        return (T) beanMap.get(cls);
    }

}
